/**
 * 此文件中新添加的方法有。
 * Array.removeOne(obj)			移除数组中的第一个obj元素,数组中有obj并且执行了移除操作返回true，否则返回false
 * Array.removeAll(obj)			移除数组中所有的obj元素，数组中有obj并且执行了移除操作返回true，否则返回false
 * String.startsWith(str)		判断字符串是否是以字符串str开头的，是就返回true，否则返回false
 * String.endWith(str)			判断字符串是否是以字符串str结束的，是就返回true，否则返回false
 * Date.format(format)			格式化日期对象，返回格式化后的日期字符串
 * $.cookie(name,value[,options])	扩展jquery，给jquery添加写cookie的方法				
 * $.cookie(name)				扩展jquery，给jquery添加获取cookie的方法
 * $.isNotBlack(str)			扩展jquery，给jqeruy添加字符串判断非空方法isNotBlack，当str为undefined，null，空白字符返回false，否则返回true
 * $.getStringLengthByBytes(str) 扩展jquery，给jqery添加获取字符串字节的长度方法getStringLengthByBytes，返回字符串的字节长度。
 * $.isInt(str)					扩展jquery，给jquery添加判断字符串是否是一个整数格式的字符串，是就返回true，否则返回false
 * $.toFix(value, precision)	扩展jquery，给jquery添加精确小数位数的方法，value小数值，precision精确的小数点后的位数，返回精确后的小数值。
 * $.exists(select)				扩展jquery，给jquery添加判断document上是否存在select选择器的元素，存在就返回true，否则就返回false。
 * 
 * 图片瀑布流的使用
 * 	var photos = new InitImage({
 * 		id: "wrap",
 * 		createWaiting: function() {},
 * 
 * 	});
 * 	参数：
 * 	id 是图片的外面的容器id。
 * 	createWaiting 蒙层函数，在图片没有加载之前的蒙层回调函数
 * 	注：
 * 		1.用div代替img标签，InitImage会自动添加img标签。
 * 		2.div中必须有imageloader,img-src,img-width,img-height,img-class这些属性。
 * img-src是图片的路径地址，img-width和img-height是图片宽高比的值，img-class是成产的img标签的class
 * 
 * 滚动加载数据
 * $.scrollToLoad(id, callback);
 * 参数：
 * 	id 添加数据的容器id
 * 	calllback 滚动的最后以后触发事件执行回调函数
 */
define(['jquery', 'masonry'], function($, Masonry) {
	
	//浏览器判断
	$.browser = {};
	$.browser.mozilla = /firefox/.test(navigator.userAgent.toLowerCase());
	$.browser.webkit = /webkit/.test(navigator.userAgent.toLowerCase());
	$.browser.opera = /opera/.test(navigator.userAgent.toLowerCase());
	$.browser.msie = /msie/.test(navigator.userAgent.toLowerCase());
	$.browser.iphone = /iphone/.test(navigator.userAgent.toLowerCase());
	
	//扩展js中的数组对象Array
	Array.prototype.removeOne = function(obj) {
		var a = this.indexOf(obj);
		if(a >= 0) {
			this.splice(a, 1);
			return true;
		}
		return false;
	};
	
	Array.prototype.removeAll = function(obj) {
		var a = this.indexOf(obj);
		while (a >= 0) {
			this.splice(a, 1);
			a = this.indexOf(obj);
			if(a < 0) {
				return true;
			}
		}
		return false;
	};

	Array.prototype.uniqueSame = function()
    {
    	this.sort();
    	var re=[this[0]];
    	for(var i = 1; i < this.length; i++)
    	{
    		if( this[i] !== re[re.length-1])
    		{
    			re.push(this[i]);
    		}
    	}
    	return re;
    }
	
	//扩展js中的字符串对象String
	String.prototype.startsWith = function(str) {
		return this.slice(0, str.length) == str;
	};
	
	String.prototype.endWidth = function(str) {
		return this.slice(this.length - str.length, this.length) == str;
	};
	
	//扩展js中的日期对象Date
	Date.prototype.format = function(format) {
		var o = {
			"M+" : this.getMonth() + 1,	//month
			"d+" : this.getDate(),		//day
			"h+" : this.getHours(),		//hour
			"m+" : this.getMinutes(),	//minute
			"s+" : this.getSeconds(),	//second
			"q+" : Math.floor((this.getMonth()+3)/3), //quarter
			"S"	: this.getMilliseconds()	//millisecond
		};
		if(/(y+)/.test(format)) {
			format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
		}
		for (var k in o) {
			if(new RegExp("(" + k + ")").test(format)) {
				format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
			}
		}
		return format;
	}
	
	/**
	 * $.cookie(name);获取key为那么的cookie值
	 * $.cookie(name, value [, options]);设置cookie
	 * @param {Object} name 	cookie的名字
	 * @param {Object} value	cookie的值
	 * @param {Object} options	options对象有三个属性：1.expires--是数字就表示多少天，或是一个date对象表示过期时间。
	 * 			2.path--路径在此路径获子路径下才可获取cookie值。3.domain--指定的网站发送请求才携带cookie。值网站地址。
	 * 			4.secure--是否使用安全套接字层 (SSL)（即仅通过 HTTPS）传输 Cookie，值为true或false。
	 */
	$.extend($, {
		cookie: function(name, value, options) {
		    if (typeof value != 'undefined') { // name and value given, set cookie
		        options = options || {};
		        if (value === null) {
		            value = '';
		            options.expires = new Date(0);
		        }
		        var expires = '';
		        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
		            var date;
		            if (typeof options.expires == 'number') {
		                date = new Date();
		                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
		            } else {
		                date = options.expires;
		            }
		            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
		        }
		        // CAUTION: Needed to parenthesize options.path and options.domain
		        // in the following expressions, otherwise they evaluate to undefined
		        // in the packed version for some reason...
		        var path = options.path ? '; path=' + (options.path) : '';
		        var domain = options.domain ? '; domain=' + (options.domain) : '';
		        var secure = options.secure ? '; secure' : '';
		        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
		        //alert(document.cookie);
		    } else { // only name given, get cookie
		        var cookieValue = null;
		        if (document.cookie && document.cookie != '') {
		            var cookies = document.cookie.split(';');
		            for (var i = 0; i < cookies.length; i++) {
		                var cookie = jQuery.trim(cookies[i]);
		                // Does this cookie string begin with the name we want?
		                if (cookie.substring(0, name.length + 1) == (name + '=')) {
		                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
		                    break;
		                }
		            }
		        }
		        return cookieValue;
		    }
		},
		// 非空检查
		isNotBlank: function(str) {
			if(typeof str == "undefined" || str == null) {
				return false;
			}
			return this.getStringLengthByBytes($.trim(str)) != 0;
		},
		// 判断是否是数组对象
		isArray : function(v){
			return toString.apply(v) === '[object Array]';
		},
		//返回byte长度
	    getStringLengthByBytes: function(str){
	    	if(typeof(str) == 'number') {
	    		str += "";
	    	}
	        return str.replace(/[^\x00-\xFF]/g, '**').length;
	    },
		
	    // 把html字符转成js字符
		html2jsstr:function(str) {
			return str.replace(/<br\/>/g,"\r\n")
					.replace(/<br>/g,"\r\n")
					.replace(/&nbsp;/g," ")
					.replace(/&amp;/g,"&")
					.replace(/&lt;/g,"<")
					.replace(/&gt;/g,">")
					.replace(/&apos;/g,"'")
					.replace(/&quot;/g,"\"");
		},
		
		// 把js字符转成html字符
		jsstr2html: function(str) {
			return str.replace(/&/g,"&amp;")
					.replace(/ /g,"&nbsp;")
					.replace(/</g,"&lt;")
					.replace(/>/g,"&gt;")
					.replace(/"/g,"&quot;")
					.replace(/'/g, "&apos;")
					.replace(/\r\n/g,"<br/>")
					.replace(/\r/g,"<br/>")
					.replace(/\n/g,"<br/>");
		},
	    
		//判断输入是否是一个整数   
	    isInt: function(str){
	        var result = str.match(/^(-|\+)?\d+$/);
	        if (result == null) 
	            return false;
	        return true;
	    },
	    
	    // 格式化浮点数
	    // value待格式化的浮点数
	    // precision保留小数位    
	    toFix: function (value, precision) {
	        var power = Math.pow(10, precision || 0);
	        return String(Math.round(value * power) / power);
	    },
	    
	    exists : function(selector) {
	    	return ($(selector).length > 0);
	    },

	    isFunc: function(func) {
	        return func && typeof func == 'function';
	    }
	});
	
	window.InitImage = function(param) {
		this.params = $.extend({}, param);
		this.$contentElements = null;
		this.masonry = null;
		this.refresh();
	};
	
	InitImage.prototype.refresh = function() {
		this.$contentElements = $("[imageloader]");
		this.initDom();
		this.bindEvents(this.$contentElements.find("img"));
		this.after(this.$contentElements.find("img"));
		$(this.$contentElements.find("img")).unveil(100, "content-body");
	};
	
	InitImage.prototype.initDom = function() {
		var _this = this;
		this.$contentElements.each(function() {
			var $content = $(this);
			//获取基本元素属性
			var imgSrc = $content.attr("img-src");
			var imgWidth = $content.attr("img-width");
			var imgHeight = $content.attr("img-height");
			var imgClass = $content.attr("img-class");
			
			//计算缩放后的img宽高
			var contentWidth = $content.width();
			var contentHeight = parseInt(imgHeight) * contentWidth / parseInt(imgWidth);
			
			//创建img元素
			var img_src = "images/error.jpg";
			var img = "<img class='"+ imgClass +" default_img' src='' data-src='"+ imgSrc +"' style='border: 1px solid #888; width: "+contentWidth+"px;height:"+contentHeight+"px;'/>";
			$content.html(img);
			
			//创建蒙层
			var waiting = null;
			if(_this.params.createWaiting && typeof _this.params.createWaiting == "function") {
				waiting = this.params.createWaiting.call(this, {});
			} else {
				// 默认蒙层
//				waiting = $("<div class='spinner'><div class='rect0'></div><div class='rect1'></div><div class='rect2'></div></div>");
//				waiting.css({
//					"margin-top": ((contentHeight - 50) / 2) + "px",
//					"margin-left": ((contentWidth - 50) / 2) + "px"
//				});
			}
			$content.prepend(waiting);
		});
	};
	
	InitImage.prototype.bindEvents = function(imgs) {
		if(this.masonry == null) {
			this.masonry = new Masonry("#" + this.params.id);
		} else {
			this.masonry.appended($("#" + this.params.id).children(":not([layout='true'])"));
		}
		imgs.load(function() {
			$(this).removeClass("default_img");
		});
	};
	
	InitImage.prototype.after = function(imgs) {
		this.$contentElements.each(function() {
			var $content = $(this);
			$content.removeAttr("img-src");
			$content.removeAttr("img-width");
			$content.removeAttr("img-height");
			$content.removeAttr("img-class");
			$content.removeAttr("imageloader");
		});
		$("#" + this.params.id).children(":not([layout='true'])").each(function() {
			$(this).attr("layout", "true");
		});
	};
	
	(function($) {
		$.fn.unveil = function(threshold, id, callback) {
			var $w = $("#" + id),
				th = threshold || 0,
				retina = window.devicePixelRatio > 1,
				attrib = retina? "data-src-retina" : "data-src",
				images = this,
				loaded;
	
			// 绑定unveil事件，加载图片
			this.one("unveil", function() {
				var source = this.getAttribute(attrib);	
				source = source || this.getAttribute("data-src");
				if (source) {
					this.setAttribute("src", source);
					if (typeof callback === "function") callback.call(this);
				}
			});
	
			function unveil() {
				// 获取视域中的image
				var inview = images.filter(function() {
					var $e = $(this);
					if ($e.is(":hidden")) return;
			
					var wt = $w.offset().top,
						wb = wt + $w.height(),
						et = $e.offset().top,
						eb = et + $e.height();
			
					return eb >= wt - th && et <= wb + th;
				});
		
				// 触发unveil事件
				loaded = inview.trigger("unveil");
				// 将已经加载的image从image对象数组中剔除
				images = images.not(loaded);
			}
	
			// 当窗口滚动的时候触发unveil方法
			$w.on("scroll.unveil resize.unveil lookup.unveil", unveil);
			unveil();
	
			return this;
		};

		$.fn.bindClick = function(callback){
            $(this).unbind("click");
            $(this).bind("touchstart", function(event){
                var clicked = $(this).attr("clicked");
                if(clicked != "true") {
                    var dom = $(this);
                    callback.call(this, event);
                    dom.attr("clicked", "true");
                    setTimeout(function(){
                        dom.removeAttr("clicked");
                    }, 500);
                }
            });
        };
		
		$.scrollToLoad = function(id, callback) {
			var $w = $("#content-body"),
				th = 100;
			if(!id) {
				$.MessageAlert({content:"$.scrollToLoad参数不正确"});
			}
			var $wrap = null;
			if(typeof id == "string") {
				$wrap = $("#" + id);
			} else if(typeof id == "object") {
				$wrap = $(wrap);
			}
			var $target = $wrap.children().last();
			
			
			
			function unveil() {
				var inview = $target.filter(function() {
					var $e = $(this);
					if ($e.is(":hidden")) return;
					
					var wb = $w.height() + $w.offset().top,
						et = $e.offset().top,
						eb = et + $e.height();
					return eb <= wb;
				});
				
				if(inview.length != 0) {
					callback.call();
					$target = $wrap.children().last();
				}
			};
				
				
			$w.on("scroll.unveil resize.unveil lookup.unveil", unveil);
			if($target.length == 0) {
				unveil();
			}
			
			return this;
		};
	})(window.jQuery || window.Zepto);
	
	/**
	 * 实现abort所有的ajax请求
	 * 
	 * @param $
	 */
	(function($) {
		$.each([ "ajaxSend", "ajaxComplete" ], function(i, type) {
			$.fn[type] = function(fn) {
				return this.on(type, fn);
			};
		});
	})(window.jQuery || window.Zepto);
	(function($) {
		var xhrPool = [];
		$(document).ajaxSend(function(e, jqXHR, options) {
			xhrPool.push(jqXHR);
		});
		$(document).ajaxComplete(function(e, jqXHR, options) {
			xhrPool = $.grep(xhrPool, function(x) {
				return x != jqXHR;
			});
		});
		$.abort = function(callback) {
			$.each(xhrPool, function(idx, jqXHR) {
				jqXHR.abort();
			});
			if(callback) {
				callback.apply(this, []);
			}
		};

		var oldbeforeunload = window.onbeforeunload;
		window.onbeforeunload = function() {
			var r = oldbeforeunload ? oldbeforeunload() : undefined;
			if (r == undefined) {
				$.abort();
			}
			return r;
		};
	})(window.jQuery || window.Zepto);
});